package suncertify.application;

import java.io.IOException;

import suncertify.application.exceptions.ServerStartException;
import suncertify.application.exceptions.ServerStopException;
import suncertify.gui.DesktopGui;
import suncertify.gui.ServerApplicationFrame;
import suncertify.remoting.RmiServer;

/**
 * Represents the application in the {@link ApplicationMode#SERVER} mode. The class extends the {@link Application}
 * class and implements the {@link ServerApplicationFrameInterface}.
 * 
 * <ul>
 * <li>This class is instantiated only once when the application is started in <code>server</code> mode.</li>
 * <li>The class overrides the {@link Application#startApplication()} abstract method which represents the starting
 * point for the server application.</li>
 * <li>This class represents the view and the controller for the {@link ServerApplicationFrame} frame class which
 * provides the server user interface. The server frame class uses this interface to retrieve data required by the
 * server user interface (e.g. the default port number), the server frame class also uses this class to execute the user
 * interactions e.g. start and stop server.</li>
 * <li></li>
 * <li></li>
 * </ul>
 * 
 * @see Application
 * 
 */
public class ServerApplication extends Application implements ServerApplicationFrameInterface {

    /**
     * Constructor. Calls the {@link Application#initializeApplication()} method.
     */
    public ServerApplication() {

	super.initializeApplication();
    }

    /**
     * Creates and shows the {@link ServerApplicationFrame} frame and passes itself as parameter to it.
     */
    public void startApplication() {

	ServerApplicationFrame serverDialog = new ServerApplicationFrame(this);
	serverDialog.setVisible(true);
    }

    /**
     * Starts the RMI server. Start server means:
     * 
     * <ol>
     * <li>One instance of the <code>RemoteContractorsAccessImpl</code> class is created and made available to client
     * applications using RMI on the <code>port</code> port number. After this function is called successfully, client
     * applications can connect to the server application and access the server's data.</li>
     * <li>After the server is started successfully the <code>filePath</code> and <code>port</code> values are save in
     * the applications properties file. If the file save fails then the user is informed with an informational message,
     * the application is not affected by this save error, the only effect of this error is that the
     * <code>filePath</code> and <code>port</code> values are not persistent.
     * </ol>
     * 
     * @param filePath
     *            Path of the database file.
     * @param port
     *            TCP port number used to publish the database on the network.
     * @throws ServerStartException
     *             Thrown if the server fails to start.
     * 
     */
    public void startServer(String filePath, int port) throws ServerStartException {

	// start the RMI server.
	RmiServer.getInstance().startRmiServer(filePath, port);

	Log.logInfo("RmiServer.getInstance().startRmiServer(filePath, port) succeeded! server started successfully.");

	// save the filePath and port to the configuration file.
	UserConfiguration.getInstance().setProperty(UserConfiguration.PROP_DATABASE_LOCATION, filePath);
	UserConfiguration.getInstance().setProperty(UserConfiguration.PROP_SERVER_PORT, Integer.toString(port));

	try {
	    UserConfiguration.getInstance().saveToFile();
	} catch (IOException e) {

	    // inform the user about the save failure.
	    DesktopGui.showErrorMessage(Strings.CAP_ERROR, Strings.getMessage(Strings.MSG_CONFIG_FILE_PORT_SAVE_ERROR,
		    e.toString()));
	}
    }

    /**
     * Stops the server, which means:
     * 
     * <ol>
     * <li>The network resources of the server are freed and the database file is closed.</li>
     * <li>No client application can connect to the server, connected client applications cannot access the data.</li>
     *</ol>
     * 
     * 
     * @throws ServerStopException
     *             Thrown if the server fails to stop.
     * 
     */
    public void stopServer() throws ServerStopException {

	RmiServer.getInstance().stopRmiServer();
    }

    /**
     * Returns the default port number used by the server to publish the data over the network. The default port number
     * is defined by the {@link java.rmi.registry.Registry#REGISTRY_PORT}
     * 
     * @return The port number.
     */
    public int getDefaultPortNumber() {
	return java.rmi.registry.Registry.REGISTRY_PORT;
    }

    /**
     * Returns the working directory of the user who runs the server application.
     * 
     * @return Working directory path.
     */
    public String getCurrentUserDirectory() {

	return super.getUserCurrentDirectory();
    }
}
